/*
 * Copyright (c) 2023 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <gtest/gtest.h>

#include <vector>

#include <securec.h>

#include "ipc_transmit_mock.h"
#include "sec_storage_ipc_proxy.h"
#include "test_helpers.h"

namespace OHOS {
namespace SeBaseServices {
namespace UnitTest {
using namespace testing;
TEST(SecStorageIpcProxyTest, SeSecStorageSetFactoryResetAuthenticationKeyProxyNullInput)
{
    {
        auto ret = SeSecStorageSetFactoryResetAuthenticationKeyProxy(nullptr, LEVEL_USER_WIPE, ALGO_NIST_P256, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }

    {
        IpcTransmitMock mock;
        EXPECT_CALL(mock, IpcTransmit).Times(Exactly(0));

        auto ret = SeSecStorageSetFactoryResetAuthenticationKeyProxy(IpcTransmitMock::MockIpcTransmit, LEVEL_USER_WIPE,
            ALGO_NIST_P256, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
}

TEST(SecStorageIpcProxyTest, SeSecStorageSetFactoryResetAuthenticationKeyProxyInvaliedInputKey)
{
    IpcTransmitMock mock;
    EXPECT_CALL(mock, IpcTransmit).Times(Exactly(0));
    StorageAuthKey key = {nullptr, 0};
    auto ret = SeSecStorageSetFactoryResetAuthenticationKeyProxy(IpcTransmitMock::MockIpcTransmit, LEVEL_USER_WIPE,
        ALGO_NIST_P256, &key);
    EXPECT_NE(ret, SUCCESS);
}

TEST(SecStorageIpcProxyTest, SeSecStorageSetFactoryResetAuthenticationKeyProxyInvaliedInputLargeKey)
{
    IpcTransmitMock mock;
    EXPECT_CALL(mock, IpcTransmit).Times(Exactly(0));
    std::vector<uint8_t> vec(8192);

    // too big size key
    StorageAuthKey key = {
        .keyData = vec.data(),
        .keySize = static_cast<uint32_t>(vec.size()),
    };
    auto ret = SeSecStorageSetFactoryResetAuthenticationKeyProxy(IpcTransmitMock::MockIpcTransmit, LEVEL_USER_WIPE,
        ALGO_NIST_P256, &key);
    EXPECT_NE(ret, SUCCESS);
}

TEST(SecStorageIpcProxyTest, SeSecStorageSetFactoryResetAuthenticationKeyProxySuccess)
{
    auto transmit = [](uint32_t cmd, const uint8_t *data, uint32_t dataLen, uint8_t *reply,
                        uint32_t *replyLen) -> ResultCode {
        EXPECT_EQ(cmd, CMD_SS_SET_FACTORY_RESET_AUTH_KEY);

        std::string expect = "02000000"                                                          // LEVEL_ALL_WIPE = 2
                             "01000000"                                                          // ALGO_SM2 = 1
                             "20000000"                                                          // keySize = 0x32
                             "ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB"; // 32 ab s
        EXPECT_EQ(TestHelpers::VectorToHexString(data, dataLen), expect);
        EXPECT_EQ(dataLen, sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint32_t) + 32);

        EXPECT_EQ(reply, nullptr);
        EXPECT_EQ(replyLen, nullptr);
        return SUCCESS;
    };

    IpcTransmitMock mock;
    EXPECT_CALL(mock, IpcTransmit).Times(Exactly(1)).WillOnce(Invoke(transmit));
    std::vector<uint8_t> vec(32, 0xab);

    // too big size key
    StorageAuthKey key = {
        .keyData = vec.data(),
        .keySize = static_cast<uint32_t>(vec.size()),
    };
    auto ret = SeSecStorageSetFactoryResetAuthenticationKeyProxy(IpcTransmitMock::MockIpcTransmit, LEVEL_ALL_WIPE,
        ALGO_SM2, &key);
    EXPECT_EQ(ret, SUCCESS);
}

TEST(SecStorageIpcProxyTest, SeSecStorageSetFactoryResetAuthenticationKeyProxyWithIpcFailed)
{
    auto transmit = [](uint32_t cmd, const uint8_t *data, uint32_t dataLen, uint8_t *reply,
                        uint32_t *replyLen) -> ResultCode {
        EXPECT_EQ(cmd, CMD_SS_SET_FACTORY_RESET_AUTH_KEY);

        std::string expect = "020000000100000020000000ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB";
        EXPECT_EQ(TestHelpers::VectorToHexString(data, dataLen), expect);
        EXPECT_EQ(dataLen, sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint32_t) + 32);

        EXPECT_EQ(reply, nullptr);
        EXPECT_EQ(replyLen, nullptr);
        return CHN_CLOSE_ERR;
    };

    IpcTransmitMock mock;
    EXPECT_CALL(mock, IpcTransmit).Times(Exactly(1)).WillOnce(Invoke(transmit));
    std::vector<uint8_t> vec(32, 0xab);

    // too big size key
    StorageAuthKey key = {
        .keyData = vec.data(),
        .keySize = static_cast<uint32_t>(vec.size()),
    };
    auto ret = SeSecStorageSetFactoryResetAuthenticationKeyProxy(IpcTransmitMock::MockIpcTransmit, LEVEL_ALL_WIPE,
        ALGO_SM2, &key);
    EXPECT_EQ(ret, CHN_CLOSE_ERR);
}

TEST(SecStorageIpcProxyTest, SeSecStorageGetFactoryResetAuthenticationAlgoProxyNullInput)
{
    {
        auto ret = SeSecStorageGetFactoryResetAuthenticationAlgoProxy(nullptr, LEVEL_USER_WIPE, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }

    {
        IpcTransmitMock mock;
        EXPECT_CALL(mock, IpcTransmit).Times(Exactly(0));

        auto ret = SeSecStorageGetFactoryResetAuthenticationAlgoProxy(IpcTransmitMock::MockIpcTransmit, LEVEL_USER_WIPE,
            nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
}

TEST(SecStorageIpcProxyTest, SeSecStorageGetFactoryResetAuthenticationAlgoProxyGoodInputAndIpcSuccess)
{
    auto transmit = [](uint32_t cmd, const uint8_t *data, uint32_t dataLen, uint8_t *reply,
                        uint32_t *replyLen) -> ResultCode {
        EXPECT_EQ(cmd, CMD_SS_GET_FACTORY_RESET_AUTH_ALGO);
        EXPECT_EQ(*(const uint32_t *)data, LEVEL_ALL_WIPE);
        EXPECT_EQ(dataLen, sizeof(uint32_t));

        EXPECT_NE(reply, nullptr);
        EXPECT_EQ(*replyLen, sizeof(uint32_t));
        return SUCCESS;
    };
    IpcTransmitMock mock;
    EXPECT_CALL(mock, IpcTransmit).Times(Exactly(1)).WillOnce(Invoke(transmit));

    FactoryResetAuthAlgo alg = ALGO_NIST_P256;
    auto ret =
        SeSecStorageGetFactoryResetAuthenticationAlgoProxy(IpcTransmitMock::MockIpcTransmit, LEVEL_ALL_WIPE, &alg);
    EXPECT_EQ(ret, SUCCESS);
}

TEST(SecStorageIpcProxyTest, SeSecStorageGetFactoryResetAuthenticationAlgoProxyGoodInputAndIpcFailed)
{
    auto transmit = [](uint32_t cmd, const uint8_t *data, uint32_t dataLen, uint8_t *reply,
                        uint32_t *replyLen) -> ResultCode {
        EXPECT_EQ(cmd, CMD_SS_GET_FACTORY_RESET_AUTH_ALGO);
        EXPECT_EQ(*(const uint32_t *)data, LEVEL_ALL_WIPE);
        EXPECT_EQ(dataLen, sizeof(uint32_t));

        EXPECT_NE(reply, nullptr);
        EXPECT_EQ(*replyLen, sizeof(uint32_t));
        return IPC_RES_DATA_ERR;
    };
    IpcTransmitMock mock;
    EXPECT_CALL(mock, IpcTransmit).Times(Exactly(1)).WillOnce(Invoke(transmit));

    FactoryResetAuthAlgo alg = ALGO_NIST_P256;
    auto ret =
        SeSecStorageGetFactoryResetAuthenticationAlgoProxy(IpcTransmitMock::MockIpcTransmit, LEVEL_ALL_WIPE, &alg);
    EXPECT_EQ(ret, IPC_RES_DATA_ERR);
}

TEST(SecStorageIpcProxyTest, SeSecStoragePrepareFactoryResetProxyNullInput)
{
    {
        auto ret = SeSecStoragePrepareFactoryResetProxy(nullptr, nullptr, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }

    {
        IpcTransmitMock mock;
        EXPECT_CALL(mock, IpcTransmit).Times(Exactly(0));

        auto ret = SeSecStoragePrepareFactoryResetProxy(IpcTransmitMock::MockIpcTransmit, nullptr, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }

    {
        IpcTransmitMock mock;
        EXPECT_CALL(mock, IpcTransmit).Times(Exactly(0));
        uint8_t data[1024] = {0};
        auto ret = SeSecStoragePrepareFactoryResetProxy(IpcTransmitMock::MockIpcTransmit, data, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
}

TEST(SecStorageIpcProxyTest, SeSecStoragePrepareFactoryResetProxyGoodInputButTransError)
{
    auto transmit = [](uint32_t cmd, const uint8_t *data, uint32_t dataLen, uint8_t *reply,
                        uint32_t *replyLen) -> ResultCode {
        EXPECT_EQ(cmd, CMD_SS_PREPARE_FACTORY_REST);

        EXPECT_EQ(data, nullptr);
        EXPECT_EQ(dataLen, 0);

        EXPECT_NE(reply, nullptr);
        EXPECT_NE(replyLen, nullptr);
        return CHN_CLOSE_ERR;
    };

    IpcTransmitMock mock;
    EXPECT_CALL(mock, IpcTransmit).Times(Exactly(1)).WillOnce(Invoke(transmit));
    uint32_t count = 1024;
    uint8_t data[1024] = {0};

    auto ret = SeSecStoragePrepareFactoryResetProxy(IpcTransmitMock::MockIpcTransmit, data, &count);
    EXPECT_EQ(ret, CHN_CLOSE_ERR);
}

TEST(SecStorageIpcProxyTest, SeSecStoragePrepareFactoryResetProxyGoodInputButRespNotRight)
{
    auto transmit = [](uint32_t cmd, const uint8_t *data, uint32_t dataLen, uint8_t *reply,
                        uint32_t *replyLen) -> ResultCode {
        EXPECT_EQ(cmd, CMD_SS_PREPARE_FACTORY_REST);

        EXPECT_EQ(data, nullptr);
        EXPECT_EQ(dataLen, 0);

        EXPECT_NE(reply, nullptr);
        EXPECT_NE(replyLen, nullptr);

        TestHelpers::VectorFillUp({1, 2, 3, 4, 5}, reply, replyLen);

        return SUCCESS;
    };

    IpcTransmitMock mock;
    EXPECT_CALL(mock, IpcTransmit).Times(Exactly(1)).WillOnce(Invoke(transmit));
    uint32_t count = 1024;
    uint8_t data[1024] = {0};

    auto ret = SeSecStoragePrepareFactoryResetProxy(IpcTransmitMock::MockIpcTransmit, data, &count);
    EXPECT_EQ(ret, IPC_RES_DATA_ERR);
}

TEST(SecStorageIpcProxyTest, SeSecStoragePrepareFactoryResetProxyGoodInputAndRespRight)
{
    auto transmit = [](uint32_t cmd, const uint8_t *data, uint32_t dataLen, uint8_t *reply,
                        uint32_t *replyLen) -> ResultCode {
        EXPECT_EQ(cmd, CMD_SS_PREPARE_FACTORY_REST);

        EXPECT_EQ(data, nullptr);
        EXPECT_EQ(dataLen, 0);

        EXPECT_NE(reply, nullptr);
        EXPECT_NE(replyLen, nullptr);

        TestHelpers::VectorFillUp({0x04, 0x00, 0x00, 0x00, 0xaa, 0xbb, 0xcc, 0xdd}, reply, replyLen);

        return SUCCESS;
    };

    IpcTransmitMock mock;
    EXPECT_CALL(mock, IpcTransmit).Times(Exactly(1)).WillOnce(Invoke(transmit));
    uint32_t count = 1024;
    uint8_t data[1024] = {0};

    auto ret = SeSecStoragePrepareFactoryResetProxy(IpcTransmitMock::MockIpcTransmit, data, &count);
    EXPECT_EQ(ret, SUCCESS);
    EXPECT_EQ(TestHelpers::VectorToHexString(data, count), "AABBCCDD");
    EXPECT_EQ(count, 4);
}

TEST(SecStorageIpcProxyTest, SeSecStorageProcessFactoryResetProxyNullInput)
{
    {
        auto ret = SeSecStorageProcessFactoryResetProxy(nullptr, LEVEL_ALL_WIPE, nullptr, 0);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }

    {
        IpcTransmitMock mock;
        EXPECT_CALL(mock, IpcTransmit).Times(Exactly(0));

        auto ret = SeSecStorageProcessFactoryResetProxy(IpcTransmitMock::MockIpcTransmit, LEVEL_ALL_WIPE, nullptr, 0);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }

    {
        IpcTransmitMock mock;
        EXPECT_CALL(mock, IpcTransmit).Times(Exactly(0));
        uint8_t data[1024] = {0};
        auto ret = SeSecStorageProcessFactoryResetProxy(IpcTransmitMock::MockIpcTransmit, LEVEL_ALL_WIPE, data, 0);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }

    {
        IpcTransmitMock mock;
        EXPECT_CALL(mock, IpcTransmit).Times(Exactly(0));
        uint8_t data[1024] = {0}; // 1024 is too big now
        auto ret = SeSecStorageProcessFactoryResetProxy(IpcTransmitMock::MockIpcTransmit, LEVEL_ALL_WIPE, data, 1024);
        EXPECT_EQ(ret, MEM_WRITE_ERR);
    }
}

TEST(SecStorageIpcProxyTest, SeSecStorageProcessFactoryResetProxyWellInputAndIpcSuccess)
{
    auto transmit = [](uint32_t cmd, const uint8_t *data, uint32_t dataLen, uint8_t *reply,
                        uint32_t *replyLen) -> ResultCode {
        EXPECT_EQ(cmd, CMD_SS_PROCESS_FACTORY_REST);

        EXPECT_NE(data, nullptr);
        EXPECT_GE(dataLen, 0);

        EXPECT_EQ(reply, nullptr);
        EXPECT_EQ(replyLen, nullptr);

        std::string expect = "01000000"   //  level = LEVEL_FACTORY_WIPE
                             "2000000000" // size = 32
                             "0102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F"; // key data
        EXPECT_EQ(TestHelpers::VectorToHexString(data, dataLen), expect);

        return SUCCESS;
    };

    IpcTransmitMock mock;
    EXPECT_CALL(mock, IpcTransmit).Times(Exactly(1)).WillOnce(Invoke(transmit));

    uint8_t data[32] = {
        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, // 0 ~ 15
        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f  // 0 ~ 15
    };
    uint32_t size = 32;
    auto ret = SeSecStorageProcessFactoryResetProxy(IpcTransmitMock::MockIpcTransmit, LEVEL_FACTORY_WIPE, data, size);
    EXPECT_EQ(ret, SUCCESS);
}

TEST(SecStorageIpcProxyTest, SeSecStorageProcessFactoryResetProxyWellInputAndIpcFailed)
{
    auto transmit = [](uint32_t cmd, const uint8_t *data, uint32_t dataLen, uint8_t *reply,
                        uint32_t *replyLen) -> ResultCode {
        EXPECT_EQ(cmd, CMD_SS_PROCESS_FACTORY_REST);

        EXPECT_NE(data, nullptr);
        EXPECT_GE(dataLen, 0);

        EXPECT_EQ(reply, nullptr);
        EXPECT_EQ(replyLen, nullptr);

        std::string expect = "01000000"   //  level = LEVEL_FACTORY_WIPE
                             "2000000000" // size = 32
                             "0102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F"; // key data
        EXPECT_EQ(TestHelpers::VectorToHexString(data, dataLen), expect);

        return CMD_APDU_CREATE_ERR;
    };

    IpcTransmitMock mock;
    EXPECT_CALL(mock, IpcTransmit).Times(Exactly(1)).WillOnce(Invoke(transmit));

    uint8_t data[32] = {
        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, // 0 ~ 15
        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f  // 0 ~ 15
    };
    uint32_t size = 32;
    auto ret = SeSecStorageProcessFactoryResetProxy(IpcTransmitMock::MockIpcTransmit, LEVEL_FACTORY_WIPE, data, size);
    EXPECT_EQ(ret, CMD_APDU_CREATE_ERR);
}

TEST(SecStorageIpcProxyTest, SeSecStorageSetToUserModeProxyNullInput)
{
    {
        auto ret = SeSecStorageSetToUserModeProxy(nullptr, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
    {
        IpcTransmitMock mock;
        EXPECT_CALL(mock, IpcTransmit).Times(Exactly(0));
        auto ret = SeSecStorageSetToUserModeProxy(IpcTransmitMock::MockIpcTransmit, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
}

TEST(SecStorageIpcProxyTest, SeSecStorageSetToUserModeProxySuccessAndIpcSuccess)
{
    auto transmit = [](uint32_t cmd, const uint8_t *data, uint32_t dataLen, uint8_t *reply,
                        uint32_t *replyLen) -> ResultCode {
        EXPECT_EQ(cmd, CMD_SS_SET_TO_USER_MODE);

        EXPECT_NE(data, nullptr);
        EXPECT_GE(dataLen, 0);

        EXPECT_EQ(reply, nullptr);
        EXPECT_EQ(replyLen, nullptr);

        std::string expect = "CDAB3412"  // 0x1234abcd
                             "21437856"; // 0x56784321

        EXPECT_EQ(TestHelpers::VectorToHexString(data, dataLen), expect);

        return SUCCESS;
    };

    IpcTransmitMock mock;
    EXPECT_CALL(mock, IpcTransmit).Times(Exactly(1)).WillOnce(Invoke(transmit));
    StorageUserModeConf config = {.pkResetable = 0x1234abcd, .slotsResetable = 0x56784321};
    auto ret = SeSecStorageSetToUserModeProxy(IpcTransmitMock::MockIpcTransmit, &config);
    EXPECT_EQ(ret, SUCCESS);
}

TEST(SecStorageIpcProxyTest, SeSecStorageSetToUserModeProxySuccessAndIpcFailed)
{
    auto transmit = [](uint32_t cmd, const uint8_t *data, uint32_t dataLen, uint8_t *reply,
                        uint32_t *replyLen) -> ResultCode {
        EXPECT_EQ(cmd, CMD_SS_SET_TO_USER_MODE);

        EXPECT_NE(data, nullptr);
        EXPECT_GE(dataLen, 0);

        EXPECT_EQ(reply, nullptr);
        EXPECT_EQ(replyLen, nullptr);

        std::string expect = "CDAB3412"  // 0x1234abcd
                             "21437856"; // 0x56784321

        EXPECT_EQ(TestHelpers::VectorToHexString(data, dataLen), expect);

        return NOT_SUPPORT;
    };

    IpcTransmitMock mock;
    EXPECT_CALL(mock, IpcTransmit).Times(Exactly(1)).WillOnce(Invoke(transmit));
    StorageUserModeConf config = {.pkResetable = 0x1234abcd, .slotsResetable = 0x56784321};
    auto ret = SeSecStorageSetToUserModeProxy(IpcTransmitMock::MockIpcTransmit, &config);
    EXPECT_EQ(ret, NOT_SUPPORT);
}

TEST(SecStorageIpcProxyTest, SeSecStorageIsSlotOperateAlgorithmSupportedProxyNullInput)
{
    {
        auto ret = SeSecStorageIsSlotOperateAlgorithmSupportedProxy(nullptr, ALGO_RAW_KEY, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
    {
        IpcTransmitMock mock;
        EXPECT_CALL(mock, IpcTransmit).Times(Exactly(0));
        auto ret =
            SeSecStorageIsSlotOperateAlgorithmSupportedProxy(IpcTransmitMock::MockIpcTransmit, ALGO_RAW_KEY, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
}

TEST(SecStorageIpcProxyTest, SeSecStorageIsSlotOperateAlgorithmSupportedProxySuccessAndIpcSucc)
{
    auto transmit = [](uint32_t cmd, const uint8_t *data, uint32_t dataLen, uint8_t *reply,
                        uint32_t *replyLen) -> ResultCode {
        EXPECT_EQ(cmd, CMD_SS_GET_SLOT_OPER_ALGORITHM);

        EXPECT_EQ(*(const uint32_t *)data, 0);
        EXPECT_EQ(dataLen, sizeof(uint32_t));

        EXPECT_EQ(*replyLen, sizeof(uint32_t));
        *(uint32_t *)reply = 0xaaaa;

        return SUCCESS;
    };

    IpcTransmitMock mock;
    EXPECT_CALL(mock, IpcTransmit).Times(Exactly(1)).WillOnce(Invoke(transmit));
    uint32_t available = 0;
    auto ret =
        SeSecStorageIsSlotOperateAlgorithmSupportedProxy(IpcTransmitMock::MockIpcTransmit, ALGO_RAW_KEY, &available);
    EXPECT_EQ(ret, SUCCESS);
    EXPECT_EQ(available, 0xaaaa);
}

TEST(SecStorageIpcProxyTest, SeSecStorageIsSlotOperateAlgorithmSupportedProxySuccessAndIpcFailed)
{
    auto transmit = [](uint32_t cmd, const uint8_t *data, uint32_t dataLen, uint8_t *reply,
                        uint32_t *replyLen) -> ResultCode {
        EXPECT_EQ(cmd, CMD_SS_GET_SLOT_OPER_ALGORITHM);

        EXPECT_EQ(*(const uint32_t *)data, 0);
        EXPECT_EQ(dataLen, sizeof(uint32_t));

        EXPECT_NE(reply, nullptr);
        EXPECT_EQ(*replyLen, sizeof(uint32_t));

        return INVALID_PERM;
    };

    IpcTransmitMock mock;
    EXPECT_CALL(mock, IpcTransmit).Times(Exactly(1)).WillOnce(Invoke(transmit));
    uint32_t available = 0;
    auto ret =
        SeSecStorageIsSlotOperateAlgorithmSupportedProxy(IpcTransmitMock::MockIpcTransmit, ALGO_RAW_KEY, &available);
    EXPECT_EQ(ret, INVALID_PERM);
    EXPECT_EQ(available, 0);
}

TEST(SecStorageIpcProxyTest, SeSecStorageIsFactoryResetAlgorithmSupportedProxyNullptr)
{
    {
        auto ret = SeSecStorageIsFactoryResetAlgorithmSupportedProxy(nullptr, ALGO_SM2, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
    {
        IpcTransmitMock mock;
        EXPECT_CALL(mock, IpcTransmit).Times(Exactly(0));
        auto ret =
            SeSecStorageIsFactoryResetAlgorithmSupportedProxy(IpcTransmitMock::MockIpcTransmit, ALGO_SM2, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
}

TEST(SecStorageIpcProxyTest, SeSecStorageIsFactoryResetAlgorithmSupportedProxySuccessAndIpcSucc)
{
    auto transmit = [](uint32_t cmd, const uint8_t *data, uint32_t dataLen, uint8_t *reply,
                        uint32_t *replyLen) -> ResultCode {
        EXPECT_EQ(cmd, CMD_SS_GET_FACTORY_RESET_ALGORITHM);

        EXPECT_EQ(*(const uint32_t *)data, 1);
        EXPECT_EQ(dataLen, sizeof(uint32_t));

        EXPECT_EQ(*replyLen, sizeof(uint32_t));
        *(uint32_t *)reply = 0xabbaa;

        return SUCCESS;
    };

    IpcTransmitMock mock;
    EXPECT_CALL(mock, IpcTransmit).Times(Exactly(1)).WillOnce(Invoke(transmit));
    uint32_t available = 0;
    auto ret =
        SeSecStorageIsFactoryResetAlgorithmSupportedProxy(IpcTransmitMock::MockIpcTransmit, ALGO_SM2, &available);
    EXPECT_EQ(ret, SUCCESS);
    EXPECT_EQ(available, 0xabbaa);
}

TEST(SecStorageIpcProxyTest, SeSecStorageIsFactoryResetAlgorithmSupportedProxySuccessAndIpcFailed)
{
    auto transmit = [](uint32_t cmd, const uint8_t *data, uint32_t dataLen, uint8_t *reply,
                        uint32_t *replyLen) -> ResultCode {
        EXPECT_EQ(cmd, CMD_SS_GET_FACTORY_RESET_ALGORITHM);

        EXPECT_EQ(*(const uint32_t *)data, 1);
        EXPECT_EQ(dataLen, sizeof(uint32_t));

        EXPECT_EQ(*replyLen, sizeof(uint32_t));
        *(uint32_t *)reply = 0xabbaa;

        return RES_APDU_FMT_ERR;
    };

    IpcTransmitMock mock;
    EXPECT_CALL(mock, IpcTransmit).Times(Exactly(1)).WillOnce(Invoke(transmit));
    uint32_t available = 0;
    auto ret =
        SeSecStorageIsFactoryResetAlgorithmSupportedProxy(IpcTransmitMock::MockIpcTransmit, ALGO_SM2, &available);
    EXPECT_EQ(ret, RES_APDU_FMT_ERR);
    EXPECT_EQ(available, 0xabbaa);
}

TEST(SecStorageIpcProxyTest, SeSecStorageAllocateSlotProxyNullptrOrInvalidInput)
{
    {
        auto ret = SeSecStorageAllocateSlotProxy(nullptr, nullptr, nullptr, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
    {
        IpcTransmitMock mock;
        EXPECT_CALL(mock, IpcTransmit).Times(Exactly(0));
        auto ret = SeSecStorageAllocateSlotProxy(IpcTransmitMock::MockIpcTransmit, nullptr, nullptr, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
    {
        IpcTransmitMock mock;
        EXPECT_CALL(mock, IpcTransmit).Times(Exactly(0));
        StorageFileName name = {0};
        auto ret = SeSecStorageAllocateSlotProxy(IpcTransmitMock::MockIpcTransmit, &name, nullptr, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
    {
        IpcTransmitMock mock;
        EXPECT_CALL(mock, IpcTransmit).Times(Exactly(0));
        StorageFileName name = {0};
        StorageSlotAttr attr;
        memset_s(&attr, sizeof(StorageSlotAttr), 0, sizeof(StorageSlotAttr));
        auto ret = SeSecStorageAllocateSlotProxy(IpcTransmitMock::MockIpcTransmit, &name, &attr, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
    {
        IpcTransmitMock mock;
        EXPECT_CALL(mock, IpcTransmit).Times(Exactly(0));
        StorageFileName name = {0};
        StorageSlotAttr attr;
        memset_s(&attr, sizeof(StorageSlotAttr), 0, sizeof(StorageSlotAttr));
        StorageAuthKey key = {.keyData = nullptr, .keySize = 0};
        auto ret = SeSecStorageAllocateSlotProxy(IpcTransmitMock::MockIpcTransmit, &name, &attr, &key);
        EXPECT_EQ(ret, MEM_WRITE_ERR);
    }
}

TEST(SecStorageIpcProxyTest, SeSecStorageAllocateSlotProxySuccessWithIpcSuccess)
{
    auto transmit = [](uint32_t cmd, const uint8_t *data, uint32_t dataLen, uint8_t *reply,
                        uint32_t *replyLen) -> ResultCode {
        EXPECT_EQ(cmd, CMD_SS_ALLOCATE_SLOT);

        std::string expect = "39393030383830300000000000000000" // name = "99008800"
                             "00000000"                         // attr.algo = 2
                             "0A000000"                         // resetLevel = 0xa
                             "64000000"                         // attr.size = 0x64
                             "0B000000"                         // authOnRead = 0xb
                             "0C000000"                         // authOnWrite = 0xc
                             "0D000000"                         // authOnFree = 0xd
                             "08000000"                         // key size = 8
                             "0102030405060708";                // key data
        EXPECT_EQ(TestHelpers::VectorToHexString(data, dataLen), expect);
        EXPECT_EQ(reply, nullptr);
        EXPECT_EQ(replyLen, nullptr);

        return SUCCESS;
    };

    IpcTransmitMock mock;
    EXPECT_CALL(mock, IpcTransmit).Times(Exactly(1)).WillOnce(Invoke(transmit));

    StorageFileName name = {0x39, 0x39, 0x30, 0x30, 0x38, 0x38, 0x30, 0x30};
    StorageSlotAttr attr;
    memset_s(&attr, sizeof(StorageSlotAttr), 0, sizeof(StorageSlotAttr));
    attr.algo = ALGO_RAW_KEY;
    attr.resetLevel = static_cast<FactoryResetLevel>(0xa);
    attr.size = 0x64;
    attr.authOnRead = 0xb;
    attr.authOnWrite = 0xc;
    attr.authOnFree = 0xd;

    uint8_t key[] = {1, 2, 3, 4, 5, 6, 7, 8};
    StorageAuthKey authKey = {.keyData = key, .keySize = sizeof(key)};

    auto ret = SeSecStorageAllocateSlotProxy(IpcTransmitMock::MockIpcTransmit, &name, &attr, &authKey);
    EXPECT_EQ(ret, SUCCESS);
}

TEST(SecStorageIpcProxyTest, SeSecStorageAllocateSlotProxySuccessWithIpcFailed)
{
    auto transmit = [](uint32_t cmd, const uint8_t *, uint32_t, uint8_t *, uint32_t *) -> ResultCode {
        EXPECT_EQ(cmd, CMD_SS_ALLOCATE_SLOT);

        return IPC_RES_FILL_UP_ERR;
    };

    IpcTransmitMock mock;
    EXPECT_CALL(mock, IpcTransmit).Times(Exactly(1)).WillOnce(Invoke(transmit));

    StorageFileName name = {0x99, 0x00, 0x88, 0x00};
    StorageSlotAttr attr;
    memset_s(&attr, sizeof(StorageSlotAttr), 0, sizeof(StorageSlotAttr));
    uint8_t key[] = {1, 2, 3, 4, 5, 6, 7, 8};
    StorageAuthKey authKey = {.keyData = key, .keySize = sizeof(key)};

    auto ret = SeSecStorageAllocateSlotProxy(IpcTransmitMock::MockIpcTransmit, &name, &attr, &authKey);
    EXPECT_EQ(ret, IPC_RES_FILL_UP_ERR);
}

TEST(SecStorageIpcProxyTest, SeSecStorageGetSlotStatusProxyWithNullptr)
{
    {
        auto ret = SeSecStorageGetSlotStatusProxy(nullptr, nullptr, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }

    {
        IpcTransmitMock mock;
        EXPECT_CALL(mock, IpcTransmit).Times(Exactly(0));
        auto ret = SeSecStorageGetSlotStatusProxy(IpcTransmitMock::MockIpcTransmit, nullptr, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }

    {
        IpcTransmitMock mock;
        EXPECT_CALL(mock, IpcTransmit).Times(Exactly(0));
        StorageFileName name = {0x99, 0x00, 0x88, 0x00};
        auto ret = SeSecStorageGetSlotStatusProxy(IpcTransmitMock::MockIpcTransmit, &name, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
}

TEST(SecStorageIpcProxyTest, SeSecStorageGetSlotStatusProxyWithNiceInputAndIpcSuccess)
{
    auto transmit = [](uint32_t cmd, const uint8_t *data, uint32_t dataLen, uint8_t *reply,
                        uint32_t *replyLen) -> ResultCode {
        EXPECT_EQ(cmd, CMD_SS_GET_SLOT_STATUS);

        std::string expect = "74657374000000000000000000000000"; // name = "test"

        EXPECT_EQ(TestHelpers::VectorToHexString(data, dataLen), expect);
        EXPECT_NE(reply, nullptr);
        EXPECT_EQ(*replyLen, sizeof(StorageSlotStatus));

        return SUCCESS;
    };

    IpcTransmitMock mock;
    EXPECT_CALL(mock, IpcTransmit).Times(Exactly(1)).WillOnce(Invoke(transmit));

    StorageFileName name = {0x74, 0x65, 0x73, 0x74};

    StorageSlotStatus status;
    auto ret = SeSecStorageGetSlotStatusProxy(IpcTransmitMock::MockIpcTransmit, &name, &status);
    EXPECT_EQ(ret, SUCCESS);
}

TEST(SecStorageIpcProxyTest, SeSecStorageGetSlotStatusProxyWithNiceInputAndIpcFailed)
{
    auto transmit = [](uint32_t cmd, const uint8_t *data, uint32_t dataLen, uint8_t *reply,
                        uint32_t *replyLen) -> ResultCode {
        EXPECT_EQ(cmd, CMD_SS_GET_SLOT_STATUS);

        std::string expect = "74657374000000000000000000000000"; // name = "test"

        EXPECT_EQ(TestHelpers::VectorToHexString(data, dataLen), expect);
        EXPECT_NE(reply, nullptr);
        EXPECT_EQ(*replyLen, sizeof(StorageSlotStatus));

        return CHN_OPEN_ERR;
    };

    IpcTransmitMock mock;
    EXPECT_CALL(mock, IpcTransmit).Times(Exactly(1)).WillOnce(Invoke(transmit));

    StorageFileName name = {0x74, 0x65, 0x73, 0x74};

    StorageSlotStatus status;
    auto ret = SeSecStorageGetSlotStatusProxy(IpcTransmitMock::MockIpcTransmit, &name, &status);
    EXPECT_EQ(ret, CHN_OPEN_ERR);
}

TEST(SecStorageIpcProxyTest, SeSecStorageWriteSlotProxyNullInput)
{
    {
        auto ret = SeSecStorageWriteSlotProxy(nullptr, nullptr, nullptr, nullptr, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
    {
        IpcTransmitMock mock;
        EXPECT_CALL(mock, IpcTransmit).Times(Exactly(0));
        auto ret = SeSecStorageWriteSlotProxy(IpcTransmitMock::MockIpcTransmit, nullptr, nullptr, nullptr, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }

    {
        IpcTransmitMock mock;
        EXPECT_CALL(mock, IpcTransmit).Times(Exactly(0));
        StorageFileName name = {0x99, 0x00, 0x88, 0x00};
        auto ret = SeSecStorageWriteSlotProxy(IpcTransmitMock::MockIpcTransmit, &name, nullptr, nullptr, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
    {
        IpcTransmitMock mock;
        EXPECT_CALL(mock, IpcTransmit).Times(Exactly(0));
        StorageFileName name = {0x99, 0x00, 0x88, 0x00};
        StorageAuthKey key = {};
        auto ret = SeSecStorageWriteSlotProxy(IpcTransmitMock::MockIpcTransmit, &name, &key, nullptr, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
    {
        IpcTransmitMock mock;
        EXPECT_CALL(mock, IpcTransmit).Times(Exactly(0));
        StorageFileName name = {0x99, 0x00, 0x88, 0x00};
        StorageAuthKey key = {nullptr, 0};
        StorageDataArea area = {1, 2};
        auto ret = SeSecStorageWriteSlotProxy(IpcTransmitMock::MockIpcTransmit, &name, &key, &area, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
}

TEST(SecStorageIpcProxyTest, SeSecStorageWriteSlotProxyWithInvalidNullInput)
{
    IpcTransmitMock mock;
    EXPECT_CALL(mock, IpcTransmit).Times(Exactly(0));

    StorageFileName name = {0x99, 0x00, 0x88, 0x00};

    StorageAuthKey key = {nullptr, 0};

    StorageDataArea area = {0xccdd, 0xeeff};

    uint8_t bufferData[] = {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x11, 0x22, 0x33, 0x44};
    StorageDataBuffer data = {bufferData, sizeof(bufferData)};

    auto ret = SeSecStorageWriteSlotProxy(IpcTransmitMock::MockIpcTransmit, &name, &key, &area, &data);
    EXPECT_EQ(ret, MEM_WRITE_ERR);
}

TEST(SecStorageIpcProxyTest, SeSecStorageWriteSlotProxyNiceInputAndIpcSucc)
{
    auto transmit = [](uint32_t cmd, const uint8_t *data, uint32_t dataLen, uint8_t *reply,
                        uint32_t *replyLen) -> ResultCode {
        EXPECT_EQ(cmd, CMD_SS_WRITE_SLOT);

        std::string expect = "74657374000000000000000000000000" // name = "test"
                             "08000000"                         // key size = 8
                             "0102030405060708"                 // key data = {1,2,3,4,5,6,7,8}
                             "DDCC"                             // area.offset = 0xccdd
                             "FFEE"                             // area.length = 0xeeff
                             "0A000000"                         // data length = 10
                             "AABBCCDDEEFF11223344"; // {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x11, 0x22, 0x33, 0x44}
        EXPECT_EQ(TestHelpers::VectorToHexString(data, dataLen), expect);
        EXPECT_EQ(reply, nullptr);
        EXPECT_EQ(replyLen, nullptr);

        return SUCCESS;
    };

    IpcTransmitMock mock;
    EXPECT_CALL(mock, IpcTransmit).Times(Exactly(1)).WillOnce(Invoke(transmit));

    StorageFileName name = {'t', 'e', 's', 't'};

    uint8_t keyData[] = {1, 2, 3, 4, 5, 6, 7, 8};
    StorageAuthKey key = {keyData, sizeof(keyData)};

    StorageDataArea area = {0xccdd, 0xeeff};

    uint8_t bufferData[] = {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x11, 0x22, 0x33, 0x44};
    StorageDataBuffer data = {bufferData, sizeof(bufferData)};

    auto ret = SeSecStorageWriteSlotProxy(IpcTransmitMock::MockIpcTransmit, &name, &key, &area, &data);
    EXPECT_EQ(ret, SUCCESS);
}

TEST(SecStorageIpcProxyTest, SeSecStorageWriteSlotProxyNiceInputAndIpcFailed)
{
    auto transmit = [](uint32_t cmd, const uint8_t *, uint32_t, uint8_t *, uint32_t *) -> ResultCode {
        EXPECT_EQ(cmd, CMD_SS_WRITE_SLOT);
        return RES_APDU_FMT_ERR;
    };

    IpcTransmitMock mock;
    EXPECT_CALL(mock, IpcTransmit).Times(Exactly(1)).WillOnce(Invoke(transmit));

    StorageFileName name = {0x99, 0x00, 0x88, 0x00};

    uint8_t keyData[] = {1, 2, 3, 4, 5, 6, 7, 8};
    StorageAuthKey key = {keyData, sizeof(keyData)};

    StorageDataArea area = {0xccdd, 0xeeff};

    uint8_t bufferData[] = {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x11, 0x22, 0x33, 0x44};
    StorageDataBuffer data = {bufferData, sizeof(bufferData)};

    auto ret = SeSecStorageWriteSlotProxy(IpcTransmitMock::MockIpcTransmit, &name, &key, &area, &data);
    EXPECT_EQ(ret, RES_APDU_FMT_ERR);
}

TEST(SecStorageIpcProxyTest, SeSecStorageReadSlotProxyNullInput)
{
    {
        auto ret = SeSecStorageReadSlotProxy(nullptr, nullptr, nullptr, nullptr, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
    {
        IpcTransmitMock mock;
        EXPECT_CALL(mock, IpcTransmit).Times(Exactly(0));
        auto ret = SeSecStorageReadSlotProxy(IpcTransmitMock::MockIpcTransmit, nullptr, nullptr, nullptr, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
    {
        IpcTransmitMock mock;
        EXPECT_CALL(mock, IpcTransmit).Times(Exactly(0));
        StorageFileName name = {0x99, 0x00, 0x88, 0x00};
        auto ret = SeSecStorageReadSlotProxy(IpcTransmitMock::MockIpcTransmit, &name, nullptr, nullptr, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
    {
        IpcTransmitMock mock;
        EXPECT_CALL(mock, IpcTransmit).Times(Exactly(0));
        StorageFileName name = {0x99, 0x00, 0x88, 0x00};
        StorageAuthKey key = {nullptr, 0};
        auto ret = SeSecStorageReadSlotProxy(IpcTransmitMock::MockIpcTransmit, &name, &key, nullptr, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
    {
        IpcTransmitMock mock;
        EXPECT_CALL(mock, IpcTransmit).Times(Exactly(0));
        StorageFileName name = {0x99, 0x00, 0x88, 0x00};
        StorageAuthKey key = {nullptr, 0};
        StorageDataArea area = {1, 2};
        auto ret = SeSecStorageReadSlotProxy(IpcTransmitMock::MockIpcTransmit, &name, &key, &area, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
}

TEST(SecStorageIpcProxyTest, SeSecStorageReadSlotProxyNiceInputButInputToBufferFailed)
{
    IpcTransmitMock mock;
    EXPECT_CALL(mock, IpcTransmit).Times(Exactly(0));
    StorageFileName name = {0x99, 0x00, 0x88, 0x00};
    StorageAuthKey key = {nullptr, 0};
    StorageDataArea area = {1, 2};
    uint8_t bufferData[] = {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x11, 0x22, 0x33, 0x44};
    StorageDataBuffer data = {bufferData, sizeof(bufferData)};
    auto ret = SeSecStorageReadSlotProxy(IpcTransmitMock::MockIpcTransmit, &name, &key, &area, &data);
    EXPECT_EQ(ret, MEM_WRITE_ERR);
}

TEST(SecStorageIpcProxyTest, SeSecStorageReadSlotProxyNiceAndIpcTransSuccess)
{
    auto transmit = [](uint32_t cmd, const uint8_t *data, uint32_t dataLen, uint8_t *reply,
                        uint32_t *replyLen) -> ResultCode {
        EXPECT_EQ(cmd, CMD_SS_READ_SLOT);

        std::string expect = "74657374696E67000000000000000000" // name = "testing"
                             "08000000"                         // key size = 8
                             "0102030405060708"                 // key data = {1,2,3,4,5,6,7,8}
                             "0100"                             // area.offset = 0x01
                             "0200";                            // area.length = 0x02

        EXPECT_EQ(TestHelpers::VectorToHexString(data, dataLen), expect);

        EXPECT_NE(reply, nullptr);
        EXPECT_NE(replyLen, nullptr);

        return SUCCESS;
    };

    IpcTransmitMock mock;
    EXPECT_CALL(mock, IpcTransmit).Times(Exactly(1)).WillOnce(Invoke(transmit));

    StorageFileName name = {'t', 'e', 's', 't', 'i', 'n', 'g'};
    uint8_t keyData[] = {1, 2, 3, 4, 5, 6, 7, 8};
    StorageAuthKey key = {keyData, sizeof(keyData)};
    StorageDataArea area = {1, 2};
    uint8_t bufferData[] = {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x11, 0x22, 0x33, 0x44};
    StorageDataBuffer data = {bufferData, sizeof(bufferData)};
    auto ret = SeSecStorageReadSlotProxy(IpcTransmitMock::MockIpcTransmit, &name, &key, &area, &data);
    EXPECT_EQ(ret, SUCCESS);
}

TEST(SecStorageIpcProxyTest, SeSecStorageReadSlotProxyNiceAndIpcTransFailed)
{
    auto transmit = [](uint32_t cmd, const uint8_t *data, uint32_t dataLen, uint8_t *reply,
                        uint32_t *replyLen) -> ResultCode {
        EXPECT_EQ(cmd, CMD_SS_READ_SLOT);

        std::string expect = "74657374696E67000000000000000000" // name = "testing"
                             "08000000"                         // key size = 8
                             "0102030405060708"                 // key data = {1,2,3,4,5,6,7,8}
                             "0100"                             // area.offset = 0x01
                             "0200";                            // area.length = 0x02

        EXPECT_EQ(TestHelpers::VectorToHexString(data, dataLen), expect);

        EXPECT_NE(reply, nullptr);
        EXPECT_NE(replyLen, nullptr);

        return RES_APDU_SW_ERR;
    };

    IpcTransmitMock mock;
    EXPECT_CALL(mock, IpcTransmit).Times(Exactly(1)).WillOnce(Invoke(transmit));

    StorageFileName name = {'t', 'e', 's', 't', 'i', 'n', 'g'};
    uint8_t keyData[] = {1, 2, 3, 4, 5, 6, 7, 8};
    StorageAuthKey key = {keyData, sizeof(keyData)};
    StorageDataArea area = {1, 2};
    uint8_t bufferData[] = {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x11, 0x22, 0x33, 0x44};
    StorageDataBuffer data = {bufferData, sizeof(bufferData)};
    auto ret = SeSecStorageReadSlotProxy(IpcTransmitMock::MockIpcTransmit, &name, &key, &area, &data);
    EXPECT_EQ(ret, RES_APDU_SW_ERR);
}

TEST(SecStorageIpcProxyTest, SeSecStorageFreeSlotProxyNullInput)
{
    {
        auto ret = SeSecStorageFreeSlotProxy(nullptr, nullptr, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
    {
        IpcTransmitMock mock;
        EXPECT_CALL(mock, IpcTransmit).Times(Exactly(0));
        auto ret = SeSecStorageFreeSlotProxy(IpcTransmitMock::MockIpcTransmit, nullptr, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
    {
        IpcTransmitMock mock;
        EXPECT_CALL(mock, IpcTransmit).Times(Exactly(0));
        StorageFileName name = {0x99, 0x00, 0x88, 0x00};
        auto ret = SeSecStorageFreeSlotProxy(IpcTransmitMock::MockIpcTransmit, &name, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
}

TEST(SecStorageIpcProxyTest, SeSecStorageFreeSlotProxyCaseInputToBufferFailed)
{
    IpcTransmitMock mock;
    EXPECT_CALL(mock, IpcTransmit).Times(Exactly(0));
    StorageFileName name = {0x99, 0x00, 0x88, 0x00};
    StorageAuthKey key = {nullptr, 0};
    auto ret = SeSecStorageFreeSlotProxy(IpcTransmitMock::MockIpcTransmit, &name, &key);
    EXPECT_EQ(ret, MEM_WRITE_ERR);
}

TEST(SecStorageIpcProxyTest, SeSecStorageFreeSlotProxyNiceInputAndIpcSucc)
{
    auto transmit = [](uint32_t cmd, const uint8_t *data, uint32_t dataLen, uint8_t *reply,
                        uint32_t *replyLen) -> ResultCode {
        EXPECT_EQ(cmd, CMD_SS_FREE_SLOT);

        std::string expect = "74657374696E67000000000000000000" // name = "testing"
                             "08000000"                         // key size = 8
                             "0102030405060708";                // key data = {1,2,3,4,5,6,7,8}

        EXPECT_EQ(TestHelpers::VectorToHexString(data, dataLen), expect);

        EXPECT_EQ(reply, nullptr);
        EXPECT_EQ(replyLen, nullptr);

        return SUCCESS;
    };

    IpcTransmitMock mock;
    EXPECT_CALL(mock, IpcTransmit).Times(Exactly(1)).WillOnce(Invoke(transmit));

    StorageFileName name = {'t', 'e', 's', 't', 'i', 'n', 'g'};
    uint8_t keyData[] = {1, 2, 3, 4, 5, 6, 7, 8};
    StorageAuthKey key = {keyData, sizeof(keyData)};
    auto ret = SeSecStorageFreeSlotProxy(IpcTransmitMock::MockIpcTransmit, &name, &key);
    EXPECT_EQ(ret, SUCCESS);
}

TEST(SecStorageIpcProxyTest, SeSecStorageFreeSlotProxyNiceInputAndIpcFailed)
{
    auto transmit = [](uint32_t cmd, const uint8_t *, uint32_t, uint8_t *, uint32_t *) -> ResultCode {
        EXPECT_EQ(cmd, CMD_SS_FREE_SLOT);

        return INVALID_PERM;
    };

    IpcTransmitMock mock;
    EXPECT_CALL(mock, IpcTransmit).Times(Exactly(1)).WillOnce(Invoke(transmit));

    StorageFileName name = {0x99, 0x00, 0x88, 0x00};
    uint8_t keyData[] = {1, 2, 3, 4, 5, 6, 7, 8};
    StorageAuthKey key = {keyData, sizeof(keyData)};
    auto ret = SeSecStorageFreeSlotProxy(IpcTransmitMock::MockIpcTransmit, &name, &key);
    EXPECT_EQ(ret, INVALID_PERM);
}

TEST(SecStorageIpcProxyTest, SeSecStorageSetAllSlotsSizeProxyNullInput)
{
    {
        auto ret = SeSecStorageSetAllSlotsSizeProxy(nullptr, nullptr, 0);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
    {
        IpcTransmitMock mock;
        EXPECT_CALL(mock, IpcTransmit).Times(Exactly(0));
        auto ret = SeSecStorageSetAllSlotsSizeProxy(IpcTransmitMock::MockIpcTransmit, nullptr, 0);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
    {
        IpcTransmitMock mock;
        EXPECT_CALL(mock, IpcTransmit).Times(Exactly(0));
        uint16_t data[] = {0};
        auto ret = SeSecStorageSetAllSlotsSizeProxy(IpcTransmitMock::MockIpcTransmit, data, 0);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
}

TEST(SecStorageIpcProxyTest, SeSecStorageSetAllSlotsSizeProxyCaseInputToBufferFailed)
{
    IpcTransmitMock mock;
    EXPECT_CALL(mock, IpcTransmit).Times(Exactly(0));
    std::vector<uint16_t> data(128, 0);
    auto ret = SeSecStorageSetAllSlotsSizeProxy(IpcTransmitMock::MockIpcTransmit, data.data(),
        static_cast<uint32_t>(data.size()));
    EXPECT_EQ(ret, INVALID_PARA_ERR_SIZE);
}

TEST(SecStorageIpcProxyTest, SeSecStorageSetAllSlotsSizeProxyCaseIpcTransSucc)
{
    auto transmit = [](uint32_t cmd, const uint8_t *data, uint32_t dataLen, uint8_t *reply,
                        uint32_t *replyLen) -> ResultCode {
        EXPECT_EQ(cmd, CMD_SS_SET_ALL_SLOT_SIZE);

        std::string expect = "06000000"                  // size = 6
                             "AAAABBBBCCCCDDDDEEEEFFFF"; // data = {0xaaaa, 0xbbbb, 0xcccc, 0xdddd, 0xeeee, 0xffff};

        EXPECT_EQ(TestHelpers::VectorToHexString(data, dataLen), expect);

        EXPECT_EQ(reply, nullptr);
        EXPECT_EQ(replyLen, nullptr);

        return SUCCESS;
    };

    IpcTransmitMock mock;
    EXPECT_CALL(mock, IpcTransmit).Times(Exactly(1)).WillOnce(Invoke(transmit));

    std::vector<uint16_t> data = {0xaaaa, 0xbbbb, 0xcccc, 0xdddd, 0xeeee, 0xffff};
    auto ret = SeSecStorageSetAllSlotsSizeProxy(IpcTransmitMock::MockIpcTransmit, data.data(),
        static_cast<uint32_t>(data.size()));
    EXPECT_EQ(ret, SUCCESS);
}

TEST(SecStorageIpcProxyTest, SeSecStorageSetAllSlotsSizeProxyCaseIpcTransFailed)
{
    auto transmit = [](uint32_t cmd, const uint8_t *data, uint32_t dataLen, uint8_t *reply,
                        uint32_t *replyLen) -> ResultCode {
        EXPECT_EQ(cmd, CMD_SS_SET_ALL_SLOT_SIZE);

        std::string expect = "06000000"                  // size = 6
                             "AAAABBBBCCCCDDDDEEEEFFFF"; // data = {0xaaaa, 0xbbbb, 0xcccc, 0xdddd, 0xeeee, 0xffff};

        EXPECT_EQ(TestHelpers::VectorToHexString(data, dataLen), expect);

        EXPECT_EQ(reply, nullptr);
        EXPECT_EQ(replyLen, nullptr);

        return INVALID_PERM;
    };

    IpcTransmitMock mock;
    EXPECT_CALL(mock, IpcTransmit).Times(Exactly(1)).WillOnce(Invoke(transmit));

    std::vector<uint16_t> data = {0xaaaa, 0xbbbb, 0xcccc, 0xdddd, 0xeeee, 0xffff};
    auto ret = SeSecStorageSetAllSlotsSizeProxy(IpcTransmitMock::MockIpcTransmit, data.data(),
        static_cast<uint32_t>(data.size()));
    EXPECT_EQ(ret, INVALID_PERM);
}

TEST(SecStorageIpcProxyTest, SeSecStorageGetAllSlotsSizeProxyNullInput)
{
    {
        auto ret = SeSecStorageGetAllSlotsSizeProxy(nullptr, nullptr, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
    {
        IpcTransmitMock mock;
        EXPECT_CALL(mock, IpcTransmit).Times(Exactly(0));
        auto ret = SeSecStorageGetAllSlotsSizeProxy(IpcTransmitMock::MockIpcTransmit, nullptr, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }

    {
        IpcTransmitMock mock;
        EXPECT_CALL(mock, IpcTransmit).Times(Exactly(0));
        uint16_t array[32];
        auto ret = SeSecStorageGetAllSlotsSizeProxy(IpcTransmitMock::MockIpcTransmit, array, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
}

TEST(SecStorageIpcProxyTest, SeSecStorageGetAllSlotsSizeProxyWithIpcTransFailed)
{
    auto transmit = [](uint32_t cmd, const uint8_t *data, uint32_t dataLen, uint8_t *reply,
                        uint32_t *replyLen) -> ResultCode {
        EXPECT_EQ(cmd, CMD_SS_GET_ALL_SLOT_SIZE);

        EXPECT_EQ(data, nullptr);
        EXPECT_EQ(dataLen, 0);

        EXPECT_NE(reply, nullptr);
        EXPECT_NE(replyLen, nullptr);

        return INVALID_PERM;
    };

    IpcTransmitMock mock;
    EXPECT_CALL(mock, IpcTransmit).Times(Exactly(1)).WillOnce(Invoke(transmit));
    uint32_t size = 32;
    uint16_t array[32];
    auto ret = SeSecStorageGetAllSlotsSizeProxy(IpcTransmitMock::MockIpcTransmit, array, &size);
    EXPECT_EQ(ret, INVALID_PERM);
}

TEST(SecStorageIpcProxyTest, SeSecStorageGetAllSlotsSizeProxyWithIpcSuccessButDecodeError)
{
    auto transmit = [](uint32_t cmd, const uint8_t *data, uint32_t dataLen, uint8_t *reply,
                        uint32_t *replyLen) -> ResultCode {
        EXPECT_EQ(cmd, CMD_SS_GET_ALL_SLOT_SIZE);

        EXPECT_EQ(data, nullptr);
        EXPECT_EQ(dataLen, 0);

        EXPECT_NE(reply, nullptr);
        EXPECT_NE(replyLen, nullptr);

        // size is 3, but only 2 slots
        std::vector<uint8_t> out = {0x03, 0x00, 0x00, 0x00, 0xab, 0xcd, 0x11, 0x22};
        TestHelpers::VectorFillUp(out, reply, replyLen);

        return SUCCESS;
    };

    IpcTransmitMock mock;
    EXPECT_CALL(mock, IpcTransmit).Times(Exactly(1)).WillOnce(Invoke(transmit));
    uint32_t size = 32;
    uint16_t array[32];
    auto ret = SeSecStorageGetAllSlotsSizeProxy(IpcTransmitMock::MockIpcTransmit, array, &size);
    EXPECT_EQ(ret, IPC_RES_DATA_ERR);
}

TEST(SecStorageIpcProxyTest, SeSecStorageGetAllSlotsSizeProxyWithIpcSuccessAndDecodeSucc)
{
    auto transmit = [](uint32_t cmd, const uint8_t *data, uint32_t dataLen, uint8_t *reply,
                        uint32_t *replyLen) -> ResultCode {
        EXPECT_EQ(cmd, CMD_SS_GET_ALL_SLOT_SIZE);

        EXPECT_EQ(data, nullptr);
        EXPECT_EQ(dataLen, 0);

        EXPECT_NE(reply, nullptr);
        EXPECT_NE(replyLen, nullptr);

        std::vector<uint8_t> out = {0x02, 0x00, 0x00, 0x00, 0xab, 0xcd, 0x11, 0x22};
        TestHelpers::VectorFillUp(out, reply, replyLen);

        return SUCCESS;
    };

    IpcTransmitMock mock;
    EXPECT_CALL(mock, IpcTransmit).Times(Exactly(1)).WillOnce(Invoke(transmit));
    uint32_t size = 32;
    uint16_t array[32];
    auto ret = SeSecStorageGetAllSlotsSizeProxy(IpcTransmitMock::MockIpcTransmit, array, &size);
    EXPECT_EQ(ret, SUCCESS);

    EXPECT_EQ(size, 2);
    EXPECT_EQ(array[0], 0xcdab);
    EXPECT_EQ(array[1], 0x2211);
}

} // namespace UnitTest
} // namespace SeBaseServices
} // namespace OHOS